/**
 * 范围验证规则
 */
import { ValidationResult } from '../types';

/**
 * 最小值和最大值验证规则选项接口
 * @property {number} [min] 最小值
 * @property {number} [max] 最大值
 */
export interface MinMaxValidationOptions {
    /** 
     * 最小值
     */
    min?: number;

    /** 
     * 最大值
     */
    max?: number;
}

/**
 * 最小值验证规则选项接口
 * @property {number} min 最小值
 */
export interface MinValidationOptions extends MinMaxValidationOptions {
    /**
     * 最小值
     */
    min: number;
}

/**
 * 最大值验证规则选项接口
 * @property {number} max 最大值
 */
export interface MaxValidationOptions extends MinMaxValidationOptions {
    /**
     * 最大值
     */
    max: number;
}

/**
 * 范围验证规则选项接口
 * @property {number} min 最小值
 * @property {number} max 最大值
 * @property {('closed' | 'open' | 'closed-open' | 'open-closed')} [rangeType] 区间类型，默认为'closed'，可选值：
 *  - `closed` 闭区间，包含边界值
 *  - `open` 开区间，不包含边界值
 *  - `closed-open` 左闭右开
 *  - `open-closed` 左开右闭
 */
export interface RangeValidationOptions {
    /** 
     * 最小值
     */
    min: number;

    /** 
     * 最大值
     */
    max: number;

    /**
     * 区间类型，默认为'closed'，可选值：
     *  - `closed` 闭区间，包含边界值
     *  - `open` 开区间，不包含边界值
     *  - `closed-open` 左闭右开
     *  - `open-closed` 左开右闭
     */
    rangeType?: 'closed' | 'open' | 'closed-open' | 'open-closed';

    /**
     * 自定义验证回调函数
     * @param {any} value - 要验证的值
     * @returns {any} 验证结果
     */
    callback?: (value: any) => any;
}

/**
 * 最小值和最大值验证规则
 * 同时验证值是否在指定的范围内
 * @param {any} value - 要验证的值
 * @param {MinMaxValidationOptions} options - 最小值和最大值验证选项
 * @param {number} [options.min] - 最小值
 * @param {number} [options.max] - 最大值
 * @returns {ValidationResult} 验证结果
 * @example
 * // 同时验证最小值和最大值
 * const result1 = validateMinMax(5, { min: 1, max: 10 });
 * console.log(result1); // { valid: true, message: undefined }
 * 
 * // 只验证最小值
 * const result2 = validateMinMax(5, { min: 3 });
 * console.log(result2); // { valid: true, message: undefined }
 * 
 * // 只验证最大值
 * const result3 = validateMinMax(5, { max: 8 });
 * console.log(result3); // { valid: true, message: undefined }
 * 
 * // 使用validateRule
 * const ruleResult = validateRule(15, { type: 'minMax', options: { min: 1, max: 10 } });
 * console.log(ruleResult); // { valid: false, message: '数值必须在1到10之间' }
 */
export function validateMinMax(value: any, options: MinMaxValidationOptions): ValidationResult {
    if (typeof value !== 'number') {
        return {
            valid: false,
            message: '请输入有效的数值'
        };
    }

    let isValid = true;
    let message = '';

    // 检查是否小于最小值
    if (options.min !== undefined && value < options.min) {
        isValid = false;
        message = `数值不能小于${options.min}`;
    }

    // 检查是否大于最大值（如果已经无效，不再覆盖错误消息）
    if (isValid && options.max !== undefined && value > options.max) {
        isValid = false;
        message = `数值不能大于${options.max}`;
    }

    // 如果同时设置了min和max，并且值在范围内，则返回更精确的错误消息
    if (options.min !== undefined && options.max !== undefined && !isValid) {
        message = `数值必须在${options.min}到${options.max}之间`;
    }

    return {
        valid: isValid,
        message: isValid ? undefined : message
    };
}

/**
 * 最小值验证规则
 * @param {any} value - 要验证的值
 * @param {MinValidationOptions} options - 最小值验证选项
 * @param {number} options.min 最小值
 * @returns {ValidationResult} 验证结果
 * @example
 * // 直接调用
 * const result = validateMin(10, { min: 5 });
 * console.log(result); // { valid: true, message: undefined }
 * 
 * // 使用validateRule
 * const ruleResult = validateRule(3, { type: 'min', options: { min: 5 } });
 * console.log(ruleResult); // { valid: false, message: '数值不能小于5' }
 */
export function validateMin(value: any, options: MinValidationOptions): ValidationResult {
    const isValid = typeof value === 'number' && value >= options.min;
    return {
        valid: isValid,
        message: isValid ? undefined : `数值不能小于${options.min}`
    };
}

/**
 * 最大值验证规则
 * @param {any} value - 要验证的值
 * @param {MaxValidationOptions} options - 最大值验证选项
 * @param {number} options.max 最大值
 * @returns {ValidationResult} 验证结果
 * @example
 * // 直接调用
 * const result = validateMax(5, { max: 10 });
 * console.log(result); // { valid: true, message: undefined }
 * 
 * // 使用validateRule
 * const ruleResult = validateRule(15, { type: 'max', options: { max: 10 } });
 * console.log(ruleResult); // { valid: false, message: '数值不能大于10' }
 */
export function validateMax(value: any, options: MaxValidationOptions): ValidationResult {
    const isValid = typeof value === 'number' && value <= options.max;
    return {
        valid: isValid,
        message: isValid ? undefined : `数值不能大于${options.max}`
    };
}

/**
 * 范围验证规则
 * @param {any} value - 要验证的值
 * @param {RangeValidationOptions} options - 范围验证选项
 * @param {number} options.min 最小值
 * @param {number} options.max 最大值
 * @param {('closed' | 'open' | 'closed-open' | 'open-closed')} [options.rangeType] 区间类型，默认为 `closed`，可选值：
 *  - `closed` 闭区间，包含边界值
 *  - `open` 开区间，不包含边界值
 *  - `closed-open` 左闭右开
 *  - `open-closed` 左开右闭
 * @returns {ValidationResult} 验证结果
 * @example
 * // 直接调用（闭区间，默认）
 * const result1 = validateRange(5, { min: 1, max: 10 });
 * console.log(result1); // { valid: true, message: undefined }
 * 
 * // 开区间验证
 * const result2 = validateRange(5, { min: 1, max: 10, rangeType: 'open' });
 * console.log(result2); // { valid: true, message: undefined }
 * 
 * // 边界值测试（开区间）
 * const result3 = validateRange(1, { min: 1, max: 10, rangeType: 'open' });
 * console.log(result3); // { valid: false, message: '值必须在(1, 10)之间' }
 * 
 * // 左闭右开区间验证
 * const result4 = validateRange(5, { min: 1, max: 10, rangeType: 'closed-open' });
 * console.log(result4); // { valid: true, message: undefined }
 * const result5 = validateRange(10, { min: 1, max: 10, rangeType: 'closed-open' });
 * console.log(result5); // { valid: false, message: '值必须在[1, 10)之间' }
 * 
 * // 左开右闭区间验证
 * const result6 = validateRange(5, { min: 1, max: 10, rangeType: 'open-closed' });
 * console.log(result6); // { valid: true, message: undefined }
 * const result7 = validateRange(1, { min: 1, max: 10, rangeType: 'open-closed' });
 * console.log(result7); // { valid: false, message: '值必须在(1, 10]之间' }
 * 
 * // 使用validateRule
 * const ruleResult = validateRule(15, { type: 'range', options: { min: 1, max: 10 } });
 * console.log(ruleResult); // { valid: false, message: '值必须在1到10之间' }
 */
export function validateRange(value: any, options: RangeValidationOptions): ValidationResult {
    if (value === undefined || value === null) {
        return {
            valid: false,
            message: '请输入数值'
        };
    }

    if (options.callback) {
        value = options.callback(value);
    }

    const numValue = Number(value);
    if (isNaN(numValue)) {
        return {
            valid: false,
            message: '请输入有效的数值'
        };
    }

    const rangeType = options.rangeType || 'closed';
    let isValid = false;
    let message = '';

    switch (rangeType) {
        case 'closed':
            // 闭区间 [min, max]
            isValid = numValue >= options.min && numValue <= options.max;
            message = `值必须在${options.min}到${options.max}之间`;
            break;
        case 'open':
            // 开区间 (min, max)
            isValid = numValue > options.min && numValue < options.max;
            message = `值必须在(${options.min}, ${options.max})之间`;
            break;
        case 'closed-open':
            // 左闭右开 [min, max)
            isValid = numValue >= options.min && numValue < options.max;
            message = `值必须在[${options.min}, ${options.max})之间`;
            break;
        case 'open-closed':
            // 左开右闭 (min, max]
            isValid = numValue > options.min && numValue <= options.max;
            message = `值必须在(${options.min}, ${options.max}]之间`;
            break;
        default:
            // 默认使用闭区间
            isValid = numValue >= options.min && numValue <= options.max;
            message = `值必须在${options.min}到${options.max}之间`;
    }

    return {
        valid: isValid,
        message: isValid ? undefined : message
    };
}